package com.xmtlxx.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.entity.*;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmtlxx.system.domain.bo.SysWorkflowBo;
import com.xmtlxx.system.domain.vo.SysNodeVo;
import com.xmtlxx.system.domain.vo.SysOperatorVo;
import com.xmtlxx.system.domain.vo.SysWorkflowVo;
import com.xmtlxx.system.mapper.*;
import com.xmtlxx.system.service.ISysWorkflowService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 工作流程Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-04-24
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysWorkflowServiceImpl implements ISysWorkflowService {

    private final SysWorkflowMapper baseMapper;

    private final SysNodeMapper sysNodeMapper;

    private final SysOperatorMapper sysOperatorMapper;

    private final SysUserMapper sysUserMapper;

    private final SysDeptMapper sysDeptMapper;

    private final SysRoleMapper sysRoleMapper;

    /**
     * 查询工作流程
     *
     * @param wid 工作流程主键
     * @return 工作流程
     */
    @Override
    public SysWorkflowVo queryById(String wid){
        SysWorkflowVo vo = baseMapper.selectVoById(wid);
        List<SysNodeVo> items = new ArrayList<>();
        //加载节点
        LambdaQueryWrapper<SysNode> nlqw = Wrappers.lambdaQuery();
        nlqw.eq(SysNode::getWid, wid);
        nlqw.orderByAsc(SysNode::getSort);
        List<SysNodeVo> nodes = sysNodeMapper.selectVoList(nlqw);
        if(nodes != null && nodes.size() > 0){
            for(SysNodeVo node : nodes){

                List<Long> objids = new ArrayList<Long>();
                List<Long> tobjids = new ArrayList<Long>();
                String deptName = "";
                String depTName = "";
                LambdaQueryWrapper<SysOperator> olqw = Wrappers.lambdaQuery();
                olqw.eq(SysOperator::getNid,node.getNid());

                //经办
                olqw.eq(SysOperator::getType,"0");
                List<SysOperatorVo> operators = sysOperatorMapper.selectVoList(olqw);

                if(operators != null && operators.size() > 0){
                    for(SysOperatorVo ope : operators){
                        objids.add(Long.valueOf(ope.getObjid()));
                        if(node.getOtype().equals("2")){
                            deptName+=ope.getName()+",";
                        }
                    }
                }

                //转办
                olqw = Wrappers.lambdaQuery();
                olqw.eq(SysOperator::getNid,node.getNid());
                olqw.eq(SysOperator::getType,"1");
                List<SysOperatorVo> toperators = sysOperatorMapper.selectVoList(olqw);

                if(toperators != null && toperators.size() > 0){
                    for(SysOperatorVo ope : toperators){
                        tobjids.add(Long.valueOf(ope.getObjid()));
                        if(node.getTtype().equals("2")){
                            depTName+=ope.getName()+",";
                        }
                    }
                }

                node.setObjIds(objids.stream().toArray(Long[]::new));
                node.setTobjIds(tobjids.stream().toArray(Long[]::new));
                node.setDeptName(deptName);
                node.setDeptTName(depTName);
                items.add(node);
            }
        }
        vo.setItems(items);
        return vo;
    }

    /**
     * 查询工作流程列表
     *
     * @param bo 工作流程
     * @return 工作流程
     */
    @Override
    public TableDataInfo<SysWorkflowVo> queryPageList(SysWorkflowBo bo, PageQuery pageQuery) {
//        LambdaQueryWrapper<SysWorkflow> lqw = buildQueryWrapper(bo);
        Page<SysWorkflowVo> result = baseMapper.selectPageSysWorkflowList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询工作流程列表
     *
     * @param bo 工作流程
     * @return 工作流程
     */
    @Override
    public List<SysWorkflowVo> queryList(SysWorkflowBo bo) {
        LambdaQueryWrapper<SysWorkflow> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<SysWorkflow> buildQueryWrapper(SysWorkflowBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysWorkflow> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), SysWorkflow::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysWorkflow::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增工作流程
     *
     * @param vo 工作流程
     * @return 结果
     */
    @Override
    public Boolean insertByBo(SysWorkflowVo vo) {
        SysWorkflow add = BeanUtil.toBean(vo, SysWorkflow.class);
        validEntityBeforeSave(add);

        //填充UUID
        add.setWid(IdUtil.simpleUUID());
        add.setDelFlag("0");
        add.setStatus("0");
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            vo.setWid(add.getWid());
        }
        //节点保存
        String nids = "";
        if(vo.getItems() != null && vo.getItems().size() > 0){
            for(SysNodeVo item : vo.getItems()){
                item.setWid(vo.getWid());
                item.setNodeno(vo.getName()+"-"+item.getSort());
                nids += item.getNodeno();
                if(StringUtils.isBlank(item.getEflag())){
                    nids+= "#";
                }
                item.setNids(nids);
                SysNode node = BeanUtil.toBean(item,SysNode.class);
                node.setNid(IdUtil.simpleUUID());
                node.setStatus("0");
                node.setDelFlag("0");
                sysNodeMapper.insert(node);

                //节点操作人
                if(item.getObjIds() != null && item.getObjIds().length > 0){
                    for(Long objid : item.getObjIds()){
                        SysOperator operator = new SysOperator();
                        operator.setOpid(IdUtil.simpleUUID());
                        operator.setNid(node.getNid());
                        operator.setObjid(objid);
                        operator.setType("0");
                        if(item.getOtype().equals("0")){
                            SysUser user = this.getSysUserById(objid);
                            if(user != null){
                                operator.setName(user.getNickName());
                            }
                        }else if(item.getOtype().equals("1")){
                            SysRole role = this.getSysRoleById(objid);
                            if(role != null){
                                operator.setName(role.getRoleName());
                            }
                        }else if(item.getOtype().equals("2")){
                            SysDept dept = this.getSysDeptById(objid);
                            if(dept != null){
                                operator.setName(dept.getDeptName());
                            }
                        }
                        sysOperatorMapper.insert(operator);
                    }
                }
                if(item.getTobjIds() != null && item.getTobjIds().length > 0){
                    for(Long objid : item.getTobjIds()){
                        SysOperator operator = new SysOperator();
                        operator.setOpid(IdUtil.simpleUUID());
                        operator.setNid(node.getNid());
                        operator.setObjid(objid);
                        operator.setType("1");
                        if(item.getTtype().equals("0")){
                            SysUser user = this.getSysUserById(objid);
                            if(user != null){
                                operator.setName(user.getNickName());
                            }
                        }else if(item.getTtype().equals("1")){
                            SysRole role = this.getSysRoleById(objid);
                            if(role != null){
                                operator.setName(role.getRoleName());
                            }
                        }else if(item.getTtype().equals("2")){
                            SysDept dept = this.getSysDeptById(objid);
                            if(dept != null){
                                operator.setName(dept.getDeptName());
                            }
                        }
                        sysOperatorMapper.insert(operator);
                    }
                }
            }
        }
        return flag;
    }

    public SysRole getSysRoleById(Long id){
       return sysRoleMapper.selectVoById(id);
    }

    public SysUser getSysUserById(Long id){
        return sysUserMapper.selectUserById(id);
    }

    public SysDept getSysDeptById(Long id){
        return sysDeptMapper.selectVoById(id);
    }

    /**
     * 修改工作流程
     *
     * @param vo 工作流程
     * @return 结果
     */
    @Override
    public Boolean updateByBo(SysWorkflowVo vo) {
        SysWorkflow update = BeanUtil.toBean(vo, SysWorkflow.class);
        validEntityBeforeSave(update);
        boolean falg = baseMapper.updateById(update) > 0;
        //节点保存
        String nids = "";
        SysNode delCon = new SysNode();
        delCon.setWid(vo.getWid());
        sysNodeMapper.deleteSysNodes(delCon);

        if(vo.getItems() != null && vo.getItems().size() > 0){
            for(SysNodeVo item : vo.getItems()){
                item.setWid(vo.getWid());
                item.setNodeno(vo.getName()+"-"+item.getSort());
                nids += item.getNodeno();
                if(StringUtils.isBlank(item.getEflag())){
                    nids+= "#";
                }
                item.setNids(nids);
                SysNode node = BeanUtil.toBean(item,SysNode.class);
                node.setNid(IdUtil.simpleUUID());
                node.setStatus("0");
                node.setDelFlag("0");
                sysNodeMapper.insert(node);

                //节点操作人
                if(item.getObjIds() != null && item.getObjIds().length > 0){
                    for(Long objid : item.getObjIds()){
                        SysOperator operator = new SysOperator();
                        operator.setOpid(IdUtil.simpleUUID());
                        operator.setNid(node.getNid());
                        operator.setObjid(objid);
                        operator.setType("0");
                        if(item.getOtype().equals("0")){
                            SysUser user = this.getSysUserById(objid);
                            if(user != null){
                                operator.setName(user.getNickName());
                            }
                        }else if(item.getOtype().equals("1")){
                            SysRole role = this.getSysRoleById(objid);
                            if(role != null){
                                operator.setName(role.getRoleName());
                            }
                        }else if(item.getOtype().equals("2")){
                            SysDept dept = this.getSysDeptById(objid);
                            if(dept != null){
                                operator.setName(dept.getDeptName());
                            }
                        }
                        sysOperatorMapper.insert(operator);
                    }
                }
                if(item.getTobjIds() != null && item.getTobjIds().length > 0){
                    for(Long objid : item.getTobjIds()){
                        SysOperator operator = new SysOperator();
                        operator.setOpid(IdUtil.simpleUUID());
                        operator.setNid(node.getNid());
                        operator.setObjid(objid);
                        operator.setType("1");
                        if(item.getTtype().equals("0")){
                            SysUser user = this.getSysUserById(objid);
                            if(user != null){
                                operator.setName(user.getNickName());
                            }
                        }else if(item.getTtype().equals("1")){
                            SysRole role = this.getSysRoleById(objid);
                            if(role != null){
                                operator.setName(role.getRoleName());
                            }
                        }else if(item.getTtype().equals("2")){
                            SysDept dept = this.getSysDeptById(objid);
                            if(dept != null){
                                operator.setName(dept.getDeptName());
                            }
                        }
                        sysOperatorMapper.insert(operator);
                    }
                }
            }
        }
        return falg;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SysWorkflow entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除工作流程
     *
     * @param ids 需要删除的工作流程主键
     * @return 结果
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for(String id : ids){
            SysWorkflowBo bo = new SysWorkflowBo();
            bo.setWid(id);
            baseMapper.deleteSysWorkflow(bo);
        }
        return true;
    }

    @Override
    public int updateWorkflowStatus(SysWorkflow enty) {
        return baseMapper.updateById(enty);
    }
}
